home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlib25 / mntlib25.zoo / bblink.c < prev    next >
C/C++ Source or Header  |  1992-09-05  |  4KB  |  136 lines

  1. /*
  2.  * block profile support for gcc.
  3.  *    ++jrb    bammi@cadence.com
  4.  */
  5. #include <compiler.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8.  
  9. /* block count struct produced by gcc -tcov */
  10. typedef struct _bb_count {
  11.     long    initialized;    /* has __bb_init_func been called */
  12.     char    *filename;    /* filename for .d file          */
  13.     long    *block_counts;  /* address of block count table   */
  14.     long    ncount;        /* sizeof block count table       */
  15.                     /* ie: # of basic blocks in file  */
  16.     struct _bb_count *next;    /* in memory link to next struct  */
  17.     char    ***addr_table;  /* addr of basic block address table */
  18.                 /* size of addr_table == ncount+1    */
  19. } BB_COUNT;
  20.  
  21. void __bb_init_func __PROTO((BB_COUNT *));
  22. static void exit_func __PROTO((void));      /* installed to be called at exit */
  23. static void save_info __PROTO((BB_COUNT *));
  24.  
  25. /* vars */
  26. static BB_COUNT *hdr = NULL;    /* list of all bb_count for which 
  27.                        __bb_init_func has been called */
  28. static char first_call = 1;    /* flags first call to __bb_init_func */
  29. static char at_exit_failed = 0; /* flag to indicate that atexit() failed */
  30.  
  31. /*
  32.  * called by gcc -tcov generated code on first entry into a function
  33.  */
  34. void __bb_init_func(bb_count)
  35. BB_COUNT *bb_count;
  36. {
  37.     if(at_exit_failed)
  38.     return;
  39.  
  40.     if(first_call)
  41.     {
  42.     if(atexit(exit_func))
  43.     {
  44.         fprintf(stderr, "Failed to install exit function. No block \
  45. profile information will be saved\n");
  46.         at_exit_failed = 1;
  47.         return;
  48.         }
  49.     first_call = 0;
  50.     }
  51.  
  52.     if(bb_count->initialized == 0)
  53.     {   /* link into list of bb_counts */
  54.     bb_count->next = hdr;
  55.     hdr = bb_count;
  56.     bb_count->initialized = 1;
  57.     }
  58. }
  59.  
  60. /*
  61.  * called on normal exit
  62.  *   write out block profile files for each bb_count struct in list.
  63.  */
  64. static void exit_func()
  65. {
  66.     BB_COUNT *p;
  67.  
  68.     for(p = hdr; p; p = p->next)
  69.        save_info(p);
  70. }
  71.  
  72. typedef struct {
  73.     long    lineno;        /* start of block */
  74.     long    count;          /* # executions (cumulative over runs)  */
  75. } DINFO;
  76.  
  77. /*
  78.  * given a bb_count struct, save info into .d file
  79.  */
  80. static void save_info(p)
  81. BB_COUNT *p;
  82. {
  83.     FILE *fp;
  84.     long i, *bcounts;
  85.     DINFO *dinfo = malloc(p->ncount * sizeof(DINFO));
  86.  
  87.     if(!dinfo)
  88.     {
  89.     fprintf(stderr, "No memory to process %s. Skipped\n", p->filename);
  90.         return;
  91.     }
  92.  
  93.     if((fp = fopen(p->filename, "r")) == NULL)
  94.     {
  95.     fprintf(stderr,"Failed to open %s for read. Skipped\n", p->filename);
  96.     free(dinfo);
  97.     return;
  98.     }
  99.     /* read .d file & accumulate counts */
  100.     for(i = 0, bcounts = p->block_counts;
  101.         fscanf(fp, "%ld%ld", &dinfo[i].lineno, &dinfo[i].count) == 2; i++)
  102.     {
  103.     if(i >= p->ncount)
  104.         {
  105.           fprintf(stderr, "Block counts in %s exceed expected %ld, rest skipped\n",
  106.             p->filename, p->ncount);
  107.           break;
  108.         }
  109.     dinfo[i].count += bcounts[i];
  110.     }
  111.     fclose(fp);
  112.     if(i < p->ncount)
  113.     {
  114.       fprintf(stderr, "Warning Block counts in %s less than expected %ld\n",
  115.             p->filename, p->ncount);
  116.     }
  117.     if((fp = fopen(p->filename, "w")) == NULL)
  118.     {
  119.     fprintf(stderr,"Failed to open %s for write. Skipped\n", p->filename);
  120.     free(dinfo);
  121.     return;
  122.     }
  123.     for(i = 0; i < p->ncount; i++)
  124.     {
  125.     if(fprintf(fp, "\t%ld\t%ld\n", dinfo[i].lineno, dinfo[i].count) == EOF)
  126.     {
  127.        fprintf(stderr,"Write Failed to %s\n", p->filename);
  128.        free(dinfo);
  129.        fclose(fp);
  130.        return;
  131.         }
  132.     }
  133.     fclose(fp);
  134.     free(dinfo);
  135. }
  136.